package hunterxhunter.greedisland.data;

import hunterxhunter.greedisland.data.enums.NenType;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;

/**
 *
 * @author Markus Schr&ouml;der
 */
public class Ring extends CipherSerializable {

    private static final String SAVE_FOLDER = "hand";
    
    //data
    private String name;//saved
    private Slot[] fixedSlots;//saved
    private Slot[] freeSlots;//not saved
    private NenType nenType;//saved
    private long time;//saved
    
    
    private boolean saveNowTime;
    
    public Ring() {
        this("", NenType.ENHANCER);
    }
    
    public Ring(String name, NenType nenType) {
        fixedSlots = new Slot[100];
        freeSlots = new Slot[45];
        
        clearFixedSlots();
        
        for(int i = 0; i < freeSlots.length; i++)
            freeSlots[i] = new Slot(100+i);
        
        this.name = name;
        this.nenType = nenType;
        this.time = System.currentTimeMillis();
    }
    
    
    //CARDS / SLOTS
    
    private void clearFixedSlots() {
        for(int i = 0; i < fixedSlots.length; i++)
            fixedSlots[i] = new Slot(i);
    }
    
    public Slot getSlot(int slotNumber) {
        if(slotNumber >= 0 && slotNumber <= 99)
            return fixedSlots[slotNumber];
        else if(slotNumber >= 100 && slotNumber <= 144)
            return freeSlots[slotNumber-100];
        return null;
    }
    
    
    //HACK
    public void getAllSpellCards() {
        int i = 1001;
        for(Slot freeSlot : freeSlots) {
            freeSlot.collectCard(i++);
        }
    }
    
    
    //IO
    
    public void save() {
        File save = new File("./" + SAVE_FOLDER);
        if(!save.exists()) {
            save.mkdir();
        }
        File ringFile = new File(save, name + ".ring");
        save(ringFile);
    }
    
    @Override
    public String getPassphrase() {
        return "hunter x hunter is a really cool manga!";
    }
    
    @Override
    public void write(ObjectOutputStream oos) throws IOException {
        oos.writeUTF(name);
        oos.writeObject(fixedSlots);
        oos.writeObject(nenType);
        if(saveNowTime)
            oos.writeLong(System.currentTimeMillis());
        else
            oos.writeLong(time);
    }

    @Override
    public void read(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        name = ois.readUTF();
        fixedSlots = (Slot[]) ois.readObject();
        nenType = (NenType) ois.readObject();
        time = (Long) ois.readLong();
        
        //ten days rule
        long tenDays = 10 * 24 * 60 * 60 * 1000;
        if(System.currentTimeMillis() > time + tenDays) {
            clearFixedSlots();
        }
        
        //TODO
        //save(file, true);//overwrite (to maybe empty fixed slots) and make time new
    }
    
    
    
    public static Ring loadRing(File file) {
        Ring r = new Ring();
        r.load(file);
        return r;
    }
    
    public static File find() {
        File save = new File("./" + SAVE_FOLDER);
        
        if(!save.exists())
            return null;
        
        for(File f : save.listFiles()) {
            if(f.getName().endsWith(".ring") && f.isFile() && !f.isHidden())
                return f;
        }
        
        return null;
    }
    
    
    
    //PROPERTIES
    
    public int numberOfFixedCards() {
        int count = 0;
        for(Slot fixedSlot : fixedSlots)
            if(fixedSlot.hasCorrectCard())
                count++;
        return count;
    }
    
    public float getProgress() {
        return (float) numberOfFixedCards() / fixedSlots.length;
    }
    
    
    //GETTER SETTER
    
    @Override
    public String toString() {
        return String.format("Ring of %s, %3.2f%% complete (last used: %s)", getName(), getProgress(), new Date(time));
    }
    
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the nenType
     */
    public NenType getNenType() {
        return nenType;
    }

    
    
}
